#include "desktopwebview.h"
#include <QWebEngineSettings>
#include <QVBoxLayout>
#include <QEventLoop>

DesktopWebView::DesktopWebView(QWidget *parent) : AbstractWebView(parent)
{
    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->setContentsMargins(0, 0, 0, 0);
    
    m_pWebView = new QWebEngineView(this);
    layout->addWidget(m_pWebView);
    
    m_pChannel = new QWebChannel(this);
    
    QWebEngineSettings *settings = m_pWebView->settings();
    settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
    settings->setAttribute(QWebEngineSettings::AutoLoadImages, true);
    settings->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
    settings->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard, true);
    settings->setAttribute(QWebEngineSettings::LocalStorageEnabled, true);
    settings->setAttribute(QWebEngineSettings::AllowGeolocationOnInsecureOrigins, true);
    settings->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, true);
    settings->setAttribute(QWebEngineSettings::AllowWindowActivationFromJavaScript, true);
    settings->setAttribute(QWebEngineSettings::PlaybackRequiresUserGesture, false);
    settings->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);

    m_pWebView->page()->setWebChannel(m_pChannel);
    
    connect(m_pWebView, &QWebEngineView::loadFinished,
            this, &AbstractWebView::loadFinished);
}

DesktopWebView::~DesktopWebView()
{
    if (m_pWebView) {
        m_pWebView->stop();
        delete m_pWebView;
    }
    if (m_pChannel) {
        delete m_pChannel;
    }
}

void DesktopWebView::setUrl(const QUrl &url)
{
    m_pWebView->setUrl(url);
}

void DesktopWebView::evaluateJavaScript(const QString &script, 
    const std::function<void(const QVariant&)>& callback)
{
    m_pWebView->page()->runJavaScript(script, callback);
}

QString DesktopWebView::syncJavaScript(const QString &script)
{
    QEventLoop loop;
    QString result;

    m_pWebView->page()->runJavaScript(script, [&](const QVariant &v) {
        result = v.toString();
        loop.quit();
    });

    loop.exec();
    return result;
}

void DesktopWebView::addJavaScriptObject(const QString &name, QObject *obj)
{
    m_pChannel->registerObject(name, obj);
}

void DesktopWebView::stop()
{
    m_pWebView->stop();
}

void DesktopWebView::reload()
{
    m_pWebView->reload();
} 
